package top.zhangjianyong.tools.indicator.strategy.impl;

import org.springframework.stereotype.Component;
import top.zhangjianyong.tools.entity.ETFData;
import top.zhangjianyong.tools.indicator.context.IndicatorContext;
import top.zhangjianyong.tools.indicator.model.TechnicalIndicatorResult;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * SMA（简单移动平均线）指标计算器
 * 支持5、10、20、60日SMA
 *
 * @author zhangjianyong
 * @date 2024/01/01
 */
@Component
public class SMAIndicator extends AbstractIndicator {

    private static final String INDICATOR_NAME = "SMA";

    @Override
    public String getName() {
        return INDICATOR_NAME;
    }

    @Override
    public int getMinDataSize() {
        return 60; // 最大周期是60日
    }

    @Override
    protected TechnicalIndicatorResult doCalculate(IndicatorContext context) {
        List<ETFData> dataList = context.getDataList();
        TechnicalIndicatorResult result = TechnicalIndicatorResult.success(getName());

        // 计算5日SMA
        BigDecimal sma5 = calculateSMA(dataList, 5);
        if (sma5 != null) {
            result.addValue("sma_5", sma5);
        }

        // 计算10日SMA
        BigDecimal sma10 = calculateSMA(dataList, 10);
        if (sma10 != null) {
            result.addValue("sma_10", sma10);
        }

        // 计算20日SMA
        BigDecimal sma20 = calculateSMA(dataList, 20);
        if (sma20 != null) {
            result.addValue("sma_20", sma20);
        }

        // 计算60日SMA
        BigDecimal sma60 = calculateSMA(dataList, 60);
        if (sma60 != null) {
            result.addValue("sma_60", sma60);
        }

        return result;
    }

    /**
     * 计算指定周期的SMA
     *
     * @param dataList K线数据列表（按时间顺序，早到晚）
     * @param period   周期
     * @return SMA值
     */
    private BigDecimal calculateSMA(List<ETFData> dataList, int period) {
        if (dataList.size() < period) {
            return null;
        }

        // 取最后period个数据点
        List<ETFData> subList = dataList.subList(dataList.size() - period, dataList.size());
        BigDecimal sum = BigDecimal.ZERO;

        for (ETFData data : subList) {
            sum = sum.add(data.getValue());
        }

        return sum.divide(new BigDecimal(period), 4, RoundingMode.HALF_UP);
    }
}

